package il.ac.bgu.cs.heuristics.graph.types;

import java.util.Set;

/**
 * 
 * @author Ronen Pinko
 * 
 */
public interface IState {

	/**
	 * returns {@code true} if there is at least one substitution in this state
	 * that contradicts some substitution in the other state
	 */
	boolean isContradicting(IState other);

	/**
	 * returns {@code true} if each substitution in this state does not
	 * contradicts constraintList
	 */
	boolean isSatisfying(Set<ISubstitution> constraintList);

	/**
	 * returns a merged state.
	 * 
	 * <p>
	 * the set of this substitutions and the other state's substitutions are
	 * merged to create the new state.
	 * </p>
	 * 
	 * <p>
	 * should use {@link #isContradicting(IState)} before calling merge to avoid
	 * {@link ContradictingStatesException}
	 * </p>
	 * 
	 * @throws ContradictingStatesException
	 *             if states are contradicting
	 */
	IState merge(IState other) throws ContradictingStatesException;

	/**
	 * see {@link #merge(IState)}
	 * 
	 * <p>
	 * if states are contradicting, this state overrides the other state
	 * </p>
	 */
	IState mergeAndOverride(IState other);

	/**
	 * returns {@code true} if for each substitution of this state there is an
	 * equal substitution in the other state
	 */
	boolean contains(IState other);

	/**
	 * returns {@code true} if for sub is contained in state
	 */
	boolean contains(ISubstitution sub);

	/**
	 * returns the number of contained substitution in this state.
	 */
	int getNumberOfContainedSubstitution(Set<ISubstitution> subs);

	/**
	 * returns a set of NOT contained substitution in this state.
	 */
	public Set<ISubstitution> getNotContainedSubstitution(
			Set<ISubstitution> subs);

	/**
	 * returns the substitutions which constitute this state
	 */
	Set<ISubstitution> getSubstitutions();

	/**
	 * since state can be imutable i need this to change state when it send to
	 * the recursion
	 */
	void swap(IState other);

	IState clone();

	/**
	 * @param substitution
	 * @return True iff one of the state's substitutions negate this
	 *         substitution
	 */
	boolean isHaveNagateSubstitution(ISubstitution substitution);

}
